﻿using Bridge.Shared.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Security;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace Bridge.Shared.Helper
{
    public class HttpHelper
    {
        private static IHttpContextAccessor _accessor;
        public static void Configure(IHttpContextAccessor httpContextAccessor)
        {
            _accessor = httpContextAccessor;
        }
        public static HttpContext HttpContext => _accessor.HttpContext;
        public static HttpRequest Request => _accessor.HttpContext.Request;
        public static HttpResponse Response => _accessor.HttpContext.Response;

        /// <summary>
        /// 获取是否是移动端请求
        /// </summary>
        /// <returns></returns>
        public static bool IsMobile()
        {
            string userAgent = Request.Headers["User-Agent"];
            string[] mobileAgents = { "iphone", "android", "phone", "mobile", "wap", "netfront", "java", "opera mobi", "opera mini", "ucweb", "windows ce", "symbian", "series", "webos", "sony", "blackberry", "dopod", "nokia", "samsung", "palmsource", "xda", "pieplus", "meizu", "midp", "cldc", "motorola", "foma", "docomo", "up.browser", "up.link", "blazer", "helio", "hosin", "huawei", "novarra", "coolpad", "webos", "techfaith", "palmsource", "alcatel", "amoi", "ktouch", "nexian", "ericsson", "philips", "sagem", "wellcom", "bunjalloo", "maui", "smartphone", "iemobile", "spice", "bird", "zte-", "longcos", "pantech", "gionee", "portalmmm", "jig browser", "hiptop", "benq", "haier", "^lct", "320x320", "240x320", "176x220", "w3c ", "acs-", "alav", "alca", "amoi", "audi", "avan", "benq", "bird", "blac", "blaz", "brew", "cell", "cldc", "cmd-", "dang", "doco", "eric", "hipt", "inno", "ipaq", "java", "jigs", "kddi", "keji", "leno", "lg-c", "lg-d", "lg-g", "lge-", "maui", "maxo", "midp", "mits", "mmef", "mobi", "mot-", "moto", "mwbp", "nec-", "newt", "noki", "oper", "palm", "pana", "pant", "phil", "play", "port", "prox", "qwap", "sage", "sams", "sany", "sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem", "smal", "smar", "sony", "sph-", "symb", "t-mo", "teli", "tim-", "tosh", "tsm-", "upg1", "upsi", "vk-v", "voda", "wap-", "wapa", "wapi", "wapp", "wapr", "webc", "winw", "winw", "xda", "xda-", "Googlebot-Mobile" };
            bool isMoblie = false;
            if (userAgent.ToString().ToLower() != null)
            {
                for (int i = 0; i < mobileAgents.Length; i++)
                {
                    if (userAgent.ToString().ToLower().IndexOf(mobileAgents[i]) >= 0)
                    {
                        isMoblie = true;
                        break;
                    }
                }
            }
            return isMoblie;
        }

        /// <summary>
        /// 通过Http请求、服务之间互相调用，会把当前HttpContext的Headers带上
        /// </summary>
        /// <param name="url">接口地址</param>
        /// <param name="data">数据，get请求传Dictionary，post请求传对象</param>
        /// <param name="method">请求方式：Get/Post、默认Post</param>
        /// <param name="contentType">请求内容类型、默认"application/json"  </param>
        /// <returns></returns>
        public static string ServiceRequest(string url, object data, string method = "Post", string contentType = "application/json", object headers = null)
        {
            if (method.ToLower() == "get")
            {
                return Get(url, (Dictionary<string, object>)data, contentType);
            }
            if (method.ToLower() == "post")
            {
                return Post(url, data, contentType, headers);
            }
            return "请求方式错误";
        }

        /// <summary>
        /// 请求Url，不发送数据
        /// </summary>
        private static string Get(string url, Dictionary<string, object> dic, string contentType = "text/html")
        {
            //拼接地址
            if (dic != null)
            {
                var strParam = string.Join("&", dic.Select(o => o.Key + "=" + o.Value));
                url = string.Concat(url, '?', strParam);
            }
            // 设置参数
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            foreach (var item in HttpContext.Request.Headers)
            {
                request.Headers.Add(item.Key, item.Value);
            }
            CookieContainer cookieContainer = new CookieContainer();
            request.CookieContainer = cookieContainer;
            request.AllowAutoRedirect = true;
            request.Method = "Get";
            request.ContentType = contentType;
            request.Headers.Add("charset", "utf-8");

            //发送请求并获取相应回应数据
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            //直到request.GetResponse()程序才开始向目标网页发送Post请求
            Stream responseStream = response.GetResponseStream();
            StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);
            //返回结果网页（html）代码
            string content = sr.ReadToEnd();
            return content;
        }

        /// <summary>
        /// 请求Url，发送数据
        /// </summary>
        private static string Post(string url, object postData, string contentType = "application/json", object headers = null)
        {
            try
            {
                string jsonData = JsonConvert.SerializeObject(postData);
                byte[] data = Encoding.UTF8.GetBytes(jsonData);

                // 设置参数
                HttpWebRequest request = null;
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    request = WebRequest.Create(url) as HttpWebRequest;
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                    request.ProtocolVersion = HttpVersion.Version11;
                    // 这里设置了协议类型。
                    ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;// SecurityProtocolType.Tls1.2; 
                    request.KeepAlive = false;
                    request.UserAgent = "";
                    ServicePointManager.CheckCertificateRevocationList = true;
                    ServicePointManager.DefaultConnectionLimit = 100;
                    ServicePointManager.Expect100Continue = false;
                }
                else
                {
                    request = (HttpWebRequest)WebRequest.Create(url);
                }
                foreach (var item in HttpContext.Request.Headers)
                {
                    request.Headers.Add(item.Key, item.Value);
                }
                if (headers != null)
                {
                    if (headers is Dictionary<string, string> keyValues)
                    {
                        foreach (var item in keyValues) request.Headers.Add(item.Key, item.Value);
                    }
                    else
                    {
                        var props = headers.GetType().GetProperties();
                        foreach (var item in props) request.Headers.Add(item.Name, item.GetValue(headers).ToString());
                    }
                }

                CookieContainer cookieContainer = new CookieContainer();
                request.CookieContainer = cookieContainer;
                request.AllowAutoRedirect = true;
                request.Method = "POST";
                request.ContentType = contentType;
                request.ContentLength = data.Length;
                Stream outstream = request.GetRequestStream();
                outstream.Write(data, 0, data.Length);
                outstream.Close();

                //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream instream = response.GetResponseStream();
                StreamReader sr = new StreamReader(instream, Encoding.UTF8);
                //返回结果网页（html）代码
                string content = sr.ReadToEnd();
                return content;
            }
            catch (Exception ex)
            {
                throw;
            }

        }

        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true; //总是接受  
        }
        public async static Task<ResponseResult<string>> SendAsync(string url,
           HttpMethod method,
           object param = null,
           object headers = null,
           string contentType = "application/json",
           CancellationToken token = default)
        {
            if (token == default) token = new CancellationTokenSource(3000).Token;
            var request = new HttpRequestMessage(method, url);
            if (method == HttpMethod.Post)
            {
                request.Headers.Add("Accept", contentType);
                HttpContent content = new StringContent(param == null ? string.Empty : param.ToJson(), Encoding.UTF8, "application/json");
                request.Content = content;
            }
            else
            {
                request.Headers.Add("Accept", "text/plain");
            }

            request.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
            request.Headers.Add("accept-encoding", "gzip, deflate, br");
            request.Headers.Add("accept-language", "zh-CN");
            request.Headers.Add("connection", "keep-alive");

            try
            {
                if (headers != null)
                {
                    if (headers is Dictionary<string, string> keyValues)
                    {
                        foreach (var item in keyValues) request.Headers.Add(item.Key, item.Value);
                    }
                    else
                    {
                        var props = headers.GetType().GetProperties();
                        foreach (var item in props) request.Headers.Add(item.Name, item.GetValue(headers).ToString());
                    }
                }
                else
                {
                    var authorization = HttpContext == null ?
                        new KeyValuePair<string, StringValues>(string.Empty, string.Empty)
                        : HttpContext.Request.Headers.FirstOrDefault(x => x.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase));
                    if (!string.IsNullOrEmpty(authorization.Key)) request.Headers.Add(authorization.Key, authorization.Value.ToString());
                }
                var httpClientFactory = _accessor.HttpContext.RequestServices.GetService<IHttpClientFactory>();
                using HttpClient client = httpClientFactory.CreateClient();
                var httpResponse = await client.SendAsync(request, token);
                var responseContent = await httpResponse.Content.ReadAsStringAsync();
                if (httpResponse.StatusCode != HttpStatusCode.OK)
                {
                    return ResponseResult<string>.Fail(responseContent);
                }

                return ResponseResult<string>.Success(string.Empty, responseContent);
            }
            catch (Exception ex)
            {
                return ResponseResult<string>.Fail(ex.Message);
            }
        }



    }
}
